package com.rengwuxian.coursecoroutines._4_flow

import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.distinctUntilChangedBy
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlin.coroutines.EmptyCoroutineContext

/**
 * distinctUntilChanged{By}()操作符
 * distinctUntilChanged() / distinctUntilChangedBy()
 *
 * 只会过滤元素，不会修改数据本身。
 * 1.distinctUntilChanged():
 *   如果连续发送两条一样的数据，新的这条就不再发送了。判断逻辑用的是kotlin的双等号，兼容null的。（java的双等号是引用的相等）
 *   比如：
 *     val flow0 = flowOf(1, 2, 2, 3, 3, 3, 3, 1)
 *     flow0.distinctUntilChanged().collect {
 *       println("flow0==> $it")
 *     }
 *     输出：
 *     flow0==> 1
 *     flow0==> 2
 *     flow0==> 3
 *     flow0==> 1
 *   可以自己提供相等判断算法：
 *   比如：
 *     val flow1 = flowOf("rengwuxian", "RengWuXian", "rengwuxian.com")
 *     flow1.distinctUntilChanged { a, b -> a.uppercase() == b.uppercase() }.collect { println("2: $it") }
 *     输出：
 *     2: rengwuxian
 *     2: rengwuxian.com
 *
 * 2.distinctUntilChangedBy{}:大括号中要生成一个key，后续相等判断会用这个key来比较。仅仅是用来生成key，不会把原始数据转换。
 *   flow1.distinctUntilChangedBy { it.uppercase() }.collect { println("3: $it") }
 *   输出：
 *   3: rengwuxian
 *   3: rengwuxian.com
 */
fun main() = runBlocking<Unit> {
  val scope = CoroutineScope(EmptyCoroutineContext)
  val flow0 = flowOf(1, 2, 2, 3, 3, 3, 3, 1)
  val flow1 = flowOf("rengwuxian", "RengWuXian", "rengwuxian.com")
  scope.launch {
    flow1.distinctUntilChanged().collect { println("1: $it") } // == equals()
    flow1.distinctUntilChanged { a, b -> a.uppercase() == b.uppercase() }.collect { println("2: $it") }
    flow1.distinctUntilChangedBy { it.uppercase() }.collect { println("3: $it") }
    flow0.distinctUntilChanged().collect {
      println("flow0==> $it")
    }
  }
  delay(10000)
}